<?php
// +-----------------------------------------------------------------------------------------------
// | 简易CMS
// +-----------------------------------------------------------------------------------------------
// | [请手动修改文件描述]
// +-----------------------------------------------------------------------------------------------
// | Author: IT果农 <htmambo@163.com> <http://www.haolie.net>
// +-----------------------------------------------------------------------------------------------
// | Version $Id$
// +-----------------------------------------------------------------------------------------------

/**
 * 系统环境检测
 *
 * @return array 系统环境数据
 */
function check_env() {
    $items = array(
        'os' => array(
        '操作系统', '不限制', '类Unix', PHP_OS, 'success'
    ), 'php' => array(
        'PHP版本', '5.3', '5.3+', PHP_VERSION, 'success'
    ), 'upload' => array(
        '附件上传', '不限制', '2M+', '未知', 'success'
    ), 'gd' => array(
        'GD库', '2.0', '2.0+', '未知', 'success'
    ), 'disk' => array(
        '磁盘空间', '5M', '不限制', '未知', 'success'
    )
    );

    // PHP环境检测
    if ($items['php'][3]<$items['php'][1]) {
        $items['php'][4] = 'error';
        session('error', true);
    }

    // 附件上传检测
    if (@ini_get('file_uploads')) {
        $items['upload'][3] = ini_get('upload_max_filesize');
    }

    // GD库检测
    $tmp = function_exists('gd_info') ? gd_info():array();
    if (empty($tmp['GD Version'])) {
        $items['gd'][3] = '未安装';
        $items['gd'][4] = 'error';
        session('error', true);
    } else {
        $items['gd'][3] = $tmp['GD Version'];
    }
    unset($tmp);

    // 磁盘空间检测
    if (function_exists('disk_free_space')) {
        $items['disk'][3] = floor(disk_free_space(INSTALL_APP_PATH)/(1024*1024)).'M';
    }

    return $items;
}

/**
 * 目录，文件读写检测
 *
 * @return array 检测数据
 */
function check_dirfile() {
    $items = array(
        array(
        'dir', '可写', 'success', '../data'
    ), array(
        'dir', '可写', 'success', '../data/runtime'
    ), array(
        'file', '可写', 'success', '../application'
    ), array(
        'file', '可写', 'success', '../application/common'
    )
    );

    foreach($items as &$val) {
        $item = INSTALL_APP_PATH.$val[3];
        if ('dir'==$val[0]) {
            if (!is_writable($item)) {
                if (is_dir($item)) {
                    $val[1] = '可读';
                    $val[2] = 'error';
                    session('error', true);
                } else {
                    $val[1] = '不存在';
                    $val[2] = 'error';
                    session('error', true);
                }
            }
        } else {
            if (file_exists($item)) {
                if (!is_writable($item)) {
                    $val[1] = '不可写';
                    $val[2] = 'error';
                    session('error', true);
                }
            } else {
                if (!is_writable(dirname($item))) {
                    $val[1] = '不存在';
                    $val[2] = 'error';
                    session('error', true);
                }
            }
        }
    }

    return $items;
}

/**
 * 函数检测
 *
 * @return array 检测数据
 */
function check_func() {
    $items = array(
        array(
        'pdo', '支持', 'success', '类'
    ), array(
        'pdo_mysql', '支持', 'success', '模块'
    ), array(
        'file_get_contents', '支持', 'success', '函数'
    ), array(
        'mb_strlen', '支持', 'success', '函数'
    )
    );

    foreach($items as &$val) {
        if (('类'==$val[3]&&!class_exists($val[0]))||('模块'==$val[3]&&!extension_loaded($val[0]))||('函数'==$val[3]&&!function_exists($val[0]))) {
            $val[1] = '不支持';
            $val[2] = 'error';
            session('error', true);
        }
    }

    return $items;
}

/**
 * 写入配置文件
 *
 * @param array $config
 *            配置信息
 */
function write_config($config, $auth) {
    if (is_array($config)) {
        // 读取配置内容
        $conf = file_get_contents(APP_PATH.'/install/data/db.tpl');
        // 替换配置项
        foreach($config as $name => $value) {
            $conf = str_replace("[{$name}]", $value, $conf);
        }

        $conf = str_replace('[auth_key]', $auth, $conf);

        // 写入应用配置文件
        if (file_put_contents(APP_PATH.'database.php', $conf)) {
            show_msg('配置文件写入成功');
        } else {
            show_msg('配置文件写入失败！', 'error');
            session('error', true);
        }
        return '';
    }
}

/**
 * 创建数据表
 *
 * @param resource $db
 *            数据库连接资源
 */
function create_tables($db, $prefix = '') {
    // 读取SQL文件
    $sql = file_get_contents(APP_PATH.'/install/data/tables.sql');
    $sql .= file_get_contents(APP_PATH.'/install/data/data.sql');
    $sql = str_replace("\r", "\n", $sql);
    $sql = explode(";\n", $sql);

    // 替换表前缀
    $orginal = config('ORIGINAL_TABLE_PREFIX');
    $sql = str_replace(" `{$orginal}", " `{$prefix}", $sql);

    // 清除注释
    $sql = preg_replace('/\n--[^\n]+\n/is', '', $sql);
    // 开始安装
    show_msg('开始安装数据库...');
    $alias = array();
    foreach($sql as $value) {
        $value = trim($value);
        if (empty($value)) {
            continue;
        }

        if (substr($value, 0, 12)=='CREATE TABLE') {
            $name = preg_replace("/^CREATE TABLE `(\w+)` .*/s", "\\1", $value);
            $result = preg_match('@COMMENT\s*=\s*[\'"](.+)[\'"]@is', $value, $comment);
            if ($result) {
                $alias[$name] = $comment[1];
                $name .= '(<strong style=\\"color:red\\">'.$comment[1].'</strong>)';
            }
            $msg = "创建数据表{$name}";
            if (false!==$db->execute($value)) {
                show_msg($msg.'...成功');
            } else {
                show_msg($msg.'...失败！', 'error');
                session('error', true);
            }
        } else if (substr($value, 0, 11)=='INSERT INTO') {
            $name = preg_replace("/^INSERT INTO `(\w+)` .*/s", "\\1", $value);
            if (isset($alias[$name])) {
                $name .= '(<strong style=\\"color:red\\">'.$alias[$name].'</strong>)';
            }
            $msg = "安装初始化数据{$name}";
            if (false!==$db->execute($value)) {
                show_msg($msg.'...成功');
            } else {
                show_msg($msg.'...失败！', 'error');
                session('error', true);
            }
        } else {
            $db->execute($value);
        }
    }
}

/**
 * 注册创始人账号
 *
 * @param \think\db\Query $db
 * @param string $prefix
 * @param array $admin
 * @param string $auth
 * @return int
 */
function register_administrator($db, $prefix, $admin, $auth) {
    show_msg('开始注册创始人帐号...');
    $password = user_md5($admin['password'], $auth);
    $data = array(
        'nickname' => '管理员', 'username' => $admin['username'], 'password' => $password, 'email' => $admin['email'], 'reg_time' => NOW_TIME, 'reg_ip' => get_client_ip(1), 'status' => 1
    );
    $result = $db->setTable($prefix.'member')->insert($data);
    $uid = $db->getLastInsID();
    show_msg('创始人帐号注册完成！');

    // 读取当前的所有权限
    $result = $db->setTable($prefix.'auth_rule')->order('id')->column('id');
    // 写入超级管理员权限
    $data = array(
        'module' => 'admin', 'type' => 1, 'title' => '超级管理员', 'description' => '这是系统管理员，拥有全部权限', 'status' => 1, 'rules' => implode(',', $result)
    );
    $db->setTable($prefix.'auth_group')->insert($data);
    show_msg('系统权限初始化完成！');

    $groupid = $db->getLastInsID();
    // 读取分类
    $result = $db->setTable($prefix.'categories')->column('catid');
    $datas = array();
    foreach($result as $v) {
        $datas[] = array(
            'group_id' => $groupid, 'extend_id' => $v, 'type' => 1
        );
    }
    $db->setTable($prefix.'auth_extend')->insertAll($datas);
    show_msg('分类授权初始化完成！');

    $data = array(
        'uid' => $uid, 'group_id' => $groupid
    );
    $db->setTable($prefix.'auth_group_access')->insert($data);
    show_msg('超级管理账号授权完成！');
    return $uid;
}

/**
 * 更新数据表
 *
 * @param resource $db
 *            数据库连接资源
 */
function update_tables($db, $prefix = '') {
    // 读取SQL文件
    $sql = file_get_contents(APP_PATH.'/install/data/update.sql');
    $sql = str_replace("\r", "\n", $sql);
    $sql = explode(";\n", $sql);

    // 替换表前缀
    $orginal = config('ORIGINAL_TABLE_PREFIX');
    $sql = str_replace(" `{$orginal}", " `{$prefix}", $sql);

    // 开始安装
    show_msg('开始升级数据库...');
    foreach($sql as $value) {
        $value = trim($value);
        if (empty($value)) {
            continue;
        }

        if (substr($value, 0, 12)=='CREATE TABLE') {
            $name = preg_replace("/^CREATE TABLE `(\w+)` .*/s", "\\1", $value);
            $msg = "创建数据表{$name}";
            if (false!==$db->execute($value)) {
                show_msg($msg.'...成功');
            } else {
                show_msg($msg.'...失败！', 'error');
                session('error', true);
            }
        } else {
            if (substr($value, 0, 8)=='UPDATE `') {
                $name = preg_replace("/^UPDATE `(\w+)` .*/s", "\\1", $value);
                $msg = "更新数据表{$name}";
            } else if (substr($value, 0, 11)=='ALTER TABLE') {
                $name = preg_replace("/^ALTER TABLE `(\w+)` .*/s", "\\1", $value);
                $msg = "修改数据表{$name}";
            } else if (substr($value, 0, 11)=='INSERT INTO') {
                $name = preg_replace("/^INSERT INTO `(\w+)` .*/s", "\\1", $value);
                $msg = "写入数据表{$name}";
            }
            if (($db->execute($value))!==false) {
                show_msg($msg.'...成功');
            } else {
                show_msg($msg.'...失败！', 'error');
                session('error', true);
            }
        }
    }
}

/**
 * 及时显示提示信息
 *
 * @param string $msg
 *            提示信息
 */
function show_msg($msg, $class = '') {
    echo "<script type=\"text/javascript\">showmsg(\"{$msg}\", \"{$class}\")</script>";
    flush();
    ob_flush();
}

/**
 * 生成系统AUTH_KEY
 */
function build_auth_key() {
    $chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $chars .= '`~!@#$%^&*()_+-=[]{};:"|,.<>/?';
    $chars = str_shuffle($chars);
    return substr($chars, 0, 40);
}
